Changedetection.io in Docker installieren und verwenden

Mit changedetection in Docker kannst du Webseiten, Preise, Texte, Shops, JSON-Antworten und viele andere Inhalte automatisch überwachen. Sobald sich etwas ändert, bekommst du eine Benachrichtigung. Fertig. Kein tägliches F5-Gedrücke mehr, kein „Ich schaue später nochmal nach“ und dann ist das Angebot natürlich weg.

Ich nutze Changedetection.io gerne für alles, was irgendwo im Web still und heimlich geändert wird. Das kann eine Changelog-Seite sein, eine Produktseite, ein bestimmter CSS-Bereich oder auch eine Seite, die erst durch JavaScript richtig Inhalt bekommt. Genau deshalb nehmen wir in diesem Docker-Stack direkt einen Headless-Chrome über Playwright mit auf.

Der normale Text-Abruf ist schnell und genügsam. Der Browser-Abruf ist schwerer, kann dafür aber moderne Webseiten rendern, Screenshots erstellen und Browser-Schritte ausführen. Beides hat seinen Platz. Wie so oft: Es kommt drauf an. Ein Satz, der in der IT fast verdächtig oft stimmt.

🛠 Voraussetzungen

Bevor es losgeht, brauchst du natürlich eine funktionierende Docker-Umgebung.
Wenn du Docker noch nicht installiert hast, findest du hier eine Schritt-für-Schritt-Anleitung, wie du das auf Ubuntu mit einem Script erledigst:

Sobald Docker läuft, kann es direkt weitergehen.

📦 Changedetection Docker-Stack vorbereiten

Ich lege mir für solche Container gerne ein eigenes Verzeichnis an. Das hält die Compose-Datei und die persistenten Daten schön zusammen.

mkdir -p /home/docker-container/changedetection
cd /home/docker-container/changedetection
nano docker-compose.yaml

Für den Stack nutze ich zwei Container:

  • changedetection-app für die Weboberfläche, Watches, Benachrichtigungen und die eigentliche Logik.
  • changedetection-chrome als Headless-Chrome-Sidecar für Playwright, Screenshots und JavaScript-Seiten.

Jeder Container bekommt eine feste IP in einem eigenen Docker-Netzwerk. Das ist nicht zwingend notwendig, macht die Umgebung aber sauberer und nachvollziehbarer.

---
services:
  changedetection-app:
    image: ghcr.io/dgtlmoon/changedetection.io:latest
    container_name: changedetection-app
    hostname: changedetection-app
    restart: unless-stopped
    environment:
      - TZ=Europe/Berlin
      - PLAYWRIGHT_DRIVER_URL=ws://changedetection-chrome:3000
      - BASE_URL=http://deine-server-ip:5010
      - FETCH_WORKERS=5
    volumes:
      - ./data:/datastore
    ports:
      - "5010:5000"
    depends_on:
      - changedetection-chrome
    networks:
      changedetection_net:
        ipv4_address: 172.28.53.10

  changedetection-chrome:
    image: dgtlmoon/sockpuppetbrowser:latest
    container_name: changedetection-chrome
    hostname: changedetection-chrome
    restart: unless-stopped
    shm_size: "2gb"
    environment:
      - SCREEN_WIDTH=1920
      - SCREEN_HEIGHT=1080
      - SCREEN_DEPTH=24
      - MAX_CONCURRENT_CHROME_PROCESSES=5
    networks:
      changedetection_net:
        ipv4_address: 172.28.53.11

networks:
  changedetection_net:
    name: changedetection.dockernetwork.local
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.53.0/24
          gateway: 172.28.53.1
          ip_range: 172.28.53.128/25

Ich nutze außen Port 5010, weil Port 5000 auf Testsystemen gerne schon von irgendetwas belegt ist. Wenn du den Standard-Port verwenden möchtest, änderst du die Port-Zeile einfach auf "5000:5000".

Das Subnetz 172.28.53.0/24 liegt im privaten Bereich. Prüfe trotzdem kurz, ob es bei dir nicht schon von einem anderen Docker-Netz verwendet wird.

docker network ls
docker network inspect changedetection.dockernetwork.local

🚀 Stack starten und prüfen

Wenn die Compose-Datei gespeichert ist, startest du den Stack wie gewohnt:

docker compose up -d
docker compose ps

Auf meinem Testsystem sah das danach so aus:

NAME                     IMAGE                                        STATUS
changedetection-app      ghcr.io/dgtlmoon/changedetection.io:latest   Up
changedetection-chrome   dgtlmoon/sockpuppetbrowser:latest            Up

Die festen IP-Adressen wurden ebenfalls korrekt gesetzt:

changedetection-app      172.28.53.10
changedetection-chrome   172.28.53.11
HTTP/1.1 200 OK

Die Weboberfläche erreichst du danach im Browser unter:

http://deine-server-ip:5010

Zum Prüfen der Logs kannst du diese Befehle nutzen:

docker logs -f changedetection-app
docker logs -f changedetection-chrome

Bei einem Browser-Check solltest du im Chrome-Container WebSocket-Verbindungen sehen. Bei mir kam der Zugriff von 172.28.53.10, also vom Changedetection-Container. Genau so soll es sein.

🧪 Playwright wirklich testen

Eine normale Watch nutzt standardmäßig meist den schnellen Text-Abruf. Für JavaScript-Seiten stellst du bei der Watch unter den erweiterten Optionen den Fetcher auf Browser steps / Playwright Chromium beziehungsweise html_webdriver.

Ich habe auf meinem Testsystem eine Watch auf https://example.com/ mit dem Browser-Fetcher angelegt und neu geprüft. Danach stand in der Watch-Datei:

{
  "fetch_backend": "html_webdriver",
  "last_check_status": 200,
  "page_title": "Example Domain",
  "fetch_time": 6.598
}

Im App-Log war außerdem zu sehen, dass Playwright eine Seite geöffnet und einen Screenshot vorbereitet hat. Das ist der Punkt, an dem du weißt: Der Headless-Chrome wird nicht nur dekorativ mitgeschleppt, sondern wirklich verwendet.

🔍 Was du mit Changedetection überwachen kannst

Changedetection.io ist erstaunlich flexibel. Du kannst es sehr simpel verwenden, aber auch ziemlich fein einstellen.

  • Komplette Webseiten, wenn dich jede sichtbare Änderung interessiert.
  • Bestimmte Bereiche per CSS- oder XPath-Selector, zum Beispiel nur eine Preistabelle.
  • Texte und Changelogs, zum Beispiel Release Notes, Statusseiten oder Dokumentationen.
  • JSON- und API-Antworten, wenn du technische Endpunkte im Blick behalten möchtest.
  • Preise und Verfügbarkeit, inklusive Restock-Erkennung und Preisänderungen.
  • JavaScript-Seiten, wenn Inhalte erst im Browser nachgeladen werden.
  • Seiten hinter einfachen Abläufen, wenn du mit Browser Steps erst klicken, suchen oder ein Formular ausfüllen musst.

Filter sind dein bester Freund

Viele Webseiten ändern ständig Kleinkram: Uhrzeiten, Werbung, Session-Texte oder zufällige Empfehlungen. Wenn du einfach die ganze Seite überwachst, bekommst du schnell zu viele Meldungen. Deshalb solltest du nach Möglichkeit mit Include-Filtern, Ignore-Text und Subtractive-Selectors arbeiten.

Ein praktisches Beispiel: Bei einer Produktseite überwachst du nicht die ganze Seite, sondern nur den Preisblock und den Verfügbarkeitsstatus. Alles andere ist nett, aber für dich wahrscheinlich egal.

🔔 Benachrichtigungen einrichten

Changedetection.io nutzt für Benachrichtigungen die Apprise-Syntax. Dadurch kannst du sehr viele Dienste anbinden, ohne für jeden Dienst eine eigene Speziallösung zu basteln.

  • E-Mail, wenn du klassische Benachrichtigungen möchtest.
  • Discord, Slack oder Microsoft Teams, wenn Meldungen in einen Kanal sollen.
  • Telegram, ntfy, Gotify oder Pushover, wenn du Push-Nachrichten bevorzugst.
  • Webhooks, wenn du die Meldung an eigene Automationen weitergeben willst.

Ein paar typische Beispiele sehen so aus:

mailto://user:pass@mail.example.de?to=admin@example.de
discord://webhook_id/webhook_token
tgram://bot_token/chat_id
ntfy://ntfy.sh/mein-topic

Benachrichtigungen kannst du global in den Einstellungen setzen oder direkt pro Watch überschreiben. Das ist praktisch, wenn wichtige Checks sofort per Push kommen sollen, während weniger kritische Änderungen nur per E-Mail landen.

Screenshots in Benachrichtigungen

Wenn dein Benachrichtigungsziel Anhänge unterstützt, kannst du auch Screenshots mitsenden. Das ist besonders praktisch bei visuellen Änderungen, Preisen oder Seiten, bei denen ein reiner Text-Diff nicht aussagekräftig genug ist.

🧭 Welche Betriebsart ist sinnvoll?

Du musst nicht jede Watch über Chrome laufen lassen. Das wäre wie mit dem Umzugswagen zum Bäcker zu fahren. Funktioniert, ist aber etwas viel.

  • html_requests ist schnell und ideal für normale HTML-Seiten, Textdateien, Changelogs und einfache API-Antworten.
  • html_webdriver ist richtig für JavaScript, Screenshots, visuelle Auswahl und Browser Steps.
  • Selenium ist noch möglich, aber für neue Setups würde ich eher Playwright verwenden.
  • browserless/chrome funktioniert in vielen Setups ebenfalls. In meinem Stack oben nutze ich aber den von Changedetection empfohlenen sockpuppetbrowser.

Meine Faustregel: Erst mit dem schnellen Abruf anfangen. Wenn die Seite leer bleibt, JavaScript braucht oder du Screenshots möchtest, schaltest du die Watch auf den Browser-Fetcher um.

🧹 Wartung und Updates

Updates sind bei diesem Setup unspektakulär. Container aktualisieren, neu erstellen, fertig. Deine Watches bleiben erhalten, weil sie im Verzeichnis ./data liegen.

cd /home/docker-container/changedetection
docker compose pull
docker compose up -d
docker image prune

Vor größeren Änderungen lohnt sich natürlich ein Backup des data-Ordners. Gerade wenn du viele Watches und Filter eingerichtet hast, willst du das nicht nochmal von Hand zusammenklicken.

📚 Quellen und weiterführende Links

Für die technische Grundlage habe ich mich an der offiziellen Dokumentation orientiert:

🔗 Fazit

Changedetection.io ist eines dieser Tools, die im Alltag schnell nützlich werden. Du richtest eine Watch ein, setzt sinnvolle Filter und bekommst Bescheid, wenn sich etwas ändert. Mehr muss es oft gar nicht sein.

Mit Docker ist die Installation überschaubar, und durch den zusätzlichen Headless-Chrome kannst du auch moderne JavaScript-Seiten sauber überwachen. Ich würde trotzdem nicht jede Watch durch den Browser jagen. Für einfache Seiten reicht der schnelle Text-Abruf völlig aus.

Mein Tipp: Starte klein, beobachte die ersten Ergebnisse und verfeinere dann deine Filter. So bekommst du nützliche Meldungen statt digitalem Konfetti.

👥 Techniverse Community

Lust auf Austausch rund um Matrix, Selfhosting und andere smarte IT-Lösungen?
In der Techniverse Community triffst du Gleichgesinnte, kannst Fragen stellen oder einfach nerdigen Talk genießen. 🚀

👉 Jetzt der Gruppe auf Matrix beitreten
~ Direkte Raumadresse: #community:techniverse.net

👉 Für lockere Gespräche abseits der Kernthemen komm in den Talkraum
~ Direkte Raumadresse: #talk:techniverse.net

Wir freuen uns, wenn du dabei bist!

Vielen Dank fürs Teilen!